/**
 * QueryUI.java
 * FlightBookingCentre
 * Phillip
 * 2014��3��22�� ����2:04:54
 */
package com.view.client;

import com.controller.client.RMIClient;
import com.dao.Flight;
import com.util.Constant;
import com.util.Printer;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import java.awt.*;
import java.awt.event.*;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

/**
 * @author Phillip
 */
public class QueryUI extends JFrame {

    int chosenRow = -1;

    Logger logger = Logger.getLogger(QueryUI.class);

    List<Flight> flights = new ArrayList<Flight>();
    private String[] columnName = {"", "FlightInfo", "Time", "Airports", "Rates"};
    private Object[][] cellData = null;
    private DefaultTableModel tableModel = new DefaultTableModel(cellData, columnName);
    private String[] yearItems = {"2014"};
    private String[] monthItems = {"03"};
    private String[] cityItems;
    private RMIClient client;
    private JLabel dpctJLabel;
    private JLabel dsctJLabel;
    private JLabel dpdtJLabel;
    private JLabel bcdtJLabel;
    private JLabel instructionJLabel;
    private JLabel instructionJLabel2;

    private JComboBox<String> bcyrJComboBox;
    private JComboBox<String> bcmtJComboBox;
    private JComboBox<String> bcdyJComboBox;
    private JComboBox<String> dpctJComboBox;
    private JComboBox<String> dsctJComboBox;
    private JComboBox<String> dpyrJComboBox;
    private JComboBox<String> dpmtJComboBox;
    private JComboBox<String> dpdyJComboBox;

    private JTable dataJTable;
    private JTable dataJTable1;

    private JScrollPane jScrollPane;
    private JScrollPane jScrollPane1;

    private JButton queryJButton;
    private JButton bookJButton;

    public QueryUI() {

        client = new RMIClient();
        PropertyConfigurator.configure(Constant.CLIENT_PRO_STRING);
        List<String> citiesList = new ArrayList<String>();
        try {
            List<String> citiesList1 = client.queryCity(1);
            List<String> citiesList2 = client.queryCity(2);
            citiesList1.addAll(citiesList2);
            HashSet<String> h = new HashSet<String>(citiesList1);
            citiesList = new ArrayList<String>(h);
        } catch (RemoteException e) {
            //undone
        }


        int count = 0;
        cityItems = new String[citiesList.size()];
        for (String string : citiesList) {
            cityItems[count] = string;
            count++;
        }

        this.setTitle("MY FLIGHT BOOKING CENTRE");
        this.setLayout(new GridBagLayout());
        GridBagConstraints constraints = new GridBagConstraints();
        this.setSize(600, 800);
        this.setResizable(false);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);

        dpdtJLabel = new JLabel("Departing Date");
        dpctJLabel = new JLabel("Departing City");
        dsctJLabel = new JLabel("Destination City");
        bcdtJLabel = new JLabel("Returning Date");


        bcyrJComboBox = new JComboBox<String>(yearItems);
        bcmtJComboBox = new JComboBox<String>(monthItems);
        bcdyJComboBox = new JComboBox<String>();
        dpctJComboBox = new JComboBox<String>(cityItems);
        dsctJComboBox = new JComboBox<String>(cityItems);
        dpyrJComboBox = new JComboBox<String>(yearItems);
        dpmtJComboBox = new JComboBox<String>(monthItems);
        dpdyJComboBox = new JComboBox<String>();
        dpdyJComboBox.addItem("");
        ;
        bcdyJComboBox.addItem("");
        for (int i = 01; i < 32; i++) {
            dpdyJComboBox.addItem("" + i);
            bcdyJComboBox.addItem("" + i);
        }
        bcyrJComboBox.setEnabled(false);
        bcmtJComboBox.setEnabled(false);
        bcdyJComboBox.setEnabled(false);
        dpctJComboBox.setEnabled(false);
        dsctJComboBox.setEnabled(false);
        dpyrJComboBox.setEnabled(false);
        dpmtJComboBox.setEnabled(false);
        dpdyJComboBox.setEnabled(false);

        dpdyJComboBox.addItemListener(new ItemListener() {

            @Override
            public void itemStateChanged(ItemEvent arg0) {
                // TODO Auto-generated method stub
                if (arg0.getStateChange() == ItemEvent.SELECTED) {
                    if (arg0.getItem().toString().equals("")) {
                        bcdyJComboBox.setSelectedItem("");
                        return;
                    }
                    bcdyJComboBox.removeAllItems();
                    bcdyJComboBox.addItem("");
                    for (int i = Integer.parseInt(arg0.getItem().toString()); i < 32; i++) {
                        bcdyJComboBox.addItem("" + i);
                    }
                    bcdyJComboBox.setSelectedItem(arg0.getItem());
                }
            }
        });

        queryJButton = new JButton("QUERY");
        bookJButton = new JButton("BOOK");
        queryJButton.setEnabled(false);
        bookJButton.setEnabled(false);
        queryJButton.addActionListener(new queryButtonHandler());
        bookJButton.addActionListener(new bookButtonHandler());

        // -------------------------------------definition of
        // dataJTable------------------------------
        final boolean[] editables = {true, false, false, false, false};
        dataJTable = new JTable(tableModel) {
            public boolean isCellEditable(int row, int column) {
                return editables[column];
            }
        };

        dataJTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        dataJTable.setRowHeight(40);
        TableColumnModel tcm = dataJTable.getColumnModel();
        TableColumn tc = tcm.getColumn(0);
        tc.setCellEditor(new DefaultCellEditor(new JCheckBox()));
        tc.setPreferredWidth(55);
        tc.setCellRenderer(new CheckBoxCellRender());
        tc = tcm.getColumn(1);
        tc.setPreferredWidth(90);
        tc.setCellRenderer(new TextAreaCellRenderer());
        tc = tcm.getColumn(2);
        tc.setCellRenderer(new TextAreaCellRenderer());
        tc = tcm.getColumn(3);
        tc.setPreferredWidth(160);
        tc.setCellRenderer(new TextAreaCellRenderer());
        tc = tcm.getColumn(4);
        tc.setPreferredWidth(160);
        tc.setCellRenderer(new TextAreaCellRenderer());

        jScrollPane = new JScrollPane();
        jScrollPane.setViewportView(dataJTable);

        dataJTable.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent e) {
                int row = dataJTable.getSelectedRow();
                int column = dataJTable.getSelectedColumn();
                Printer.p("row: " + row);
                Printer.p("col: " + column);
                Printer.p(chosenRow);
                if (column == 0) {
                    if (chosenRow == row) {
                        if (!(boolean) (dataJTable.getValueAt(row, column))) {
                            Printer.p((boolean) (dataJTable.getValueAt(row, column)) + "");
                            bookJButton.setEnabled(false);
                            chosenRow = -1;
                        } else {
                            Printer.p((boolean) (dataJTable.getValueAt(row, column)) + "");
                            bookJButton.setEnabled(true);
                        }

                    } else {
                        chosenRow = row;
                        bookJButton.setEnabled(true);
                        for (int i = 0; i < row; i++) {
                            dataJTable.setValueAt(new Boolean(false), i, 0);
                            dataJTable.updateUI();
                        }
                        for (int i = row + 1; i < dataJTable.getRowCount(); i++) {
                            dataJTable.setValueAt(new Boolean(false), i, 0);
                            dataJTable.updateUI();
                        }
                    }
                }

            }
        });

        // ------------------------------------------------------------------------------------------

        final JProgressBar progressBar = new JProgressBar();
        progressBar.setStringPainted(true);
        progressBar.setIndeterminate(false);
        progressBar.setString("Initialization...");
        new Progress(progressBar, bcyrJComboBox, bcmtJComboBox, bcdyJComboBox, dpctJComboBox, dsctJComboBox, dpyrJComboBox, dpmtJComboBox,
                dpdyJComboBox, queryJButton).start();

        constraints.gridx = 0;
        constraints.gridy = 0;
        constraints.fill = GridBagConstraints.BOTH;
        constraints.insets = new Insets(10, 5, 10, 5);
        this.add(dpctJLabel, constraints);

        constraints.gridx = 1;
        constraints.gridwidth = 3;
        this.add(dpctJComboBox, constraints);

        constraints.gridx = 4;
        constraints.gridwidth = 1;
        this.add(dsctJLabel, constraints);

        constraints.gridx = 5;
        constraints.gridwidth = 3;
        this.add(dsctJComboBox, constraints);

        constraints.gridx = 0;
        constraints.gridy = 1;
        constraints.gridwidth = 1;
        this.add(dpdtJLabel, constraints);

        constraints.gridx = 1;
        this.add(dpyrJComboBox, constraints);

        constraints.gridx = 2;
        this.add(dpmtJComboBox, constraints);

        constraints.gridx = 3;
        this.add(dpdyJComboBox, constraints);

        constraints.gridx = 4;
        this.add(bcdtJLabel, constraints);

        constraints.gridx = 5;
        this.add(bcyrJComboBox, constraints);

        constraints.gridx = 6;
        this.add(bcmtJComboBox, constraints);

        constraints.gridx = 7;
        this.add(bcdyJComboBox, constraints);

        constraints.gridy = 2;
        constraints.gridx = 0;
        constraints.gridwidth = 8;
        constraints.gridheight = 6;
        constraints.insets = new Insets(20, 5, 20, 5);
        this.add(jScrollPane, constraints);

        constraints.gridy = 8;
        constraints.gridx = 0;
        constraints.gridwidth = 4;
        constraints.gridheight = 1;
        constraints.insets = new Insets(20, 5, 20, 5);
        this.add(queryJButton, constraints);

        constraints.gridx = 4;
        this.add(bookJButton, constraints);

        constraints.gridx = 0;
        constraints.gridy = 9;
        constraints.gridwidth = 8;
        this.add(progressBar, constraints);

        this.setVisible(true);

        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                client.bye();
            }
        });

    }

    /**
     * @param args
     */
    public static void main(String[] args) {

        new QueryUI();
    }

    private JTable setFlightInfoTable() {

        jScrollPane.setViewportView(dataJTable);
        dataJTable.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent e) {
                int row = dataJTable.getSelectedRow();
                int column = dataJTable.getSelectedColumn();
                Printer.p("row: " + row);
                Printer.p("col: " + column);
                Printer.p(chosenRow);
                if (column == 0) {
                    if (chosenRow == row) {
                        if (!(boolean) (dataJTable.getValueAt(row, column))) {
                            Printer.p((boolean) (dataJTable.getValueAt(row, column)) + "");
                            bookJButton.setEnabled(false);
                            chosenRow = -1;
                        } else {
                            Printer.p((boolean) (dataJTable.getValueAt(row, column)) + "");
                            bookJButton.setEnabled(true);
                        }

                    } else {
                        chosenRow = row;
                        bookJButton.setEnabled(true);
                        for (int i = 0; i < row; i++) {
                            dataJTable.setValueAt(new Boolean(false), i, 0);
                            dataJTable.updateUI();
                        }
                        for (int i = row + 1; i < dataJTable.getRowCount(); i++) {
                            dataJTable.setValueAt(new Boolean(false), i, 0);
                            dataJTable.updateUI();
                        }
                    }
                }

            }
        });

        return dataJTable;

    }

    private JTable setAirlineTable(String airline1, String airline2) {
        String[] colName = {"depart", "arrive", airline1, airline2};
        Object[][] dataObjects = null;
        DefaultTableModel dtm = new DefaultTableModel(dataObjects, colName);
        dataJTable1 = new JTable(dtm);
        TableColumnModel tcm = dataJTable1.getColumnModel();
        TableColumn tc = tcm.getColumn(0);
        tc.setPreferredWidth(70);

        jScrollPane.setViewportView(dataJTable1);
        jScrollPane.revalidate();

        return dataJTable1;
    }

    public void fillTable(String[][] strings) {

        DefaultTableModel defaultTableModel = (DefaultTableModel) dataJTable.getModel();
        defaultTableModel.setRowCount(0);
        Object[] temp = new Object[]{new Boolean(false), "", "", "", ""};

        for (int i = 0; i < strings.length; i++) {
            defaultTableModel.addRow(temp);
            for (int j = 0; j < strings[i].length; j++) {
                defaultTableModel.setValueAt(strings[i][j], i, j + 1);
            }
        }
        this.revalidate();
    }

    private class queryButtonHandler implements ActionListener {

        private List<Flight> tempFlights = new ArrayList<Flight>();

        private String[][] tableContent = null;

        public void actionPerformed(ActionEvent event) {

            String dpctString = dpctJComboBox.getSelectedItem().toString();
            String dsctString = dsctJComboBox.getSelectedItem().toString();
            bookJButton.setEnabled(false);
            if (dpdyJComboBox.getSelectedItem().toString() == "" && bcdyJComboBox.getSelectedItem().toString() == "") {

                String isSupport1 = "";
                String isSupport2 = "";
                try {
                    isSupport1 = client.queryAirline(1, dpctString, dsctString);
                    isSupport2 = client.queryAirline(2, dpctString, dsctString);

                } catch (RemoteException e) {
                    //undone
                }
                logger.debug(isSupport1 + ", " + isSupport2);
                if (dataJTable.getMouseListeners().length > 0) {
                    dataJTable.removeMouseListener(dataJTable.getMouseListeners()[0]);
                }
                setAirlineTable(isSupport1.substring(12, 21), isSupport2.substring(12, 18));
                String[] tempStrings = new String[5];
                tempStrings[0] = dpctString;
                tempStrings[1] = dsctString;
                if (!isSupport1.substring(0, 12).equals(Constant.NOTSUPPORTED_STRING)) {
                    tempStrings[2] = "√";
                } else {
                    tempStrings[2] = "x";
                }
                if (!isSupport2.substring(0, 12).equals(Constant.NOTSUPPORTED_STRING)) {
                    tempStrings[3] = "√";
                } else {
                    tempStrings[3] = "x";
                }

                DefaultTableModel dtm = (DefaultTableModel) dataJTable1.getModel();
                dtm.setRowCount(0);
                dtm.addRow(tempStrings);
                dataJTable.updateUI();
                return;
            } else if (dpdyJComboBox.getSelectedItem().toString() != "" && bcdyJComboBox.getSelectedItem().toString() != "") {
                chosenRow = -1;
                setFlightInfoTable();

                String deptDateString = "2014-03-" + dpdyJComboBox.getSelectedItem().toString();
                String returnDateString = "2014-03-" + bcdyJComboBox.getSelectedItem().toString();
                try {
                    List<Flight> tempFlight1 = client.queryFlights(1, dpctString, dsctString, deptDateString, returnDateString);
                    List<Flight> tempFlight2 = client.queryFlights(2, dpctString, dsctString, deptDateString, returnDateString);
                    tempFlights.addAll(tempFlight1);
                    tempFlights.addAll(tempFlight2);
                } catch (RemoteException e) {
                    //undone
                }

                if (tempFlights == null) {
                    JOptionPane.showMessageDialog(null, "No Available Tickets!", "Info", JOptionPane.INFORMATION_MESSAGE);
                    return;
                }
                flights = new ArrayList<Flight>(tempFlights);
                Printer.p(tempFlights.get(0).getPriceString());
                tableContent = new String[tempFlights.size() / 2][4];

                for (int i = 0; i < tempFlights.size() / 2; i++) {
                    tableContent[i][0] = tempFlights.get(2 * i).getAirlineString() + Constant.CR_LF + tempFlights.get(2 * i).getFligthNOString()
                            + Constant.CR_LF + tempFlights.get(2 * i + 1).getAirlineString() + Constant.CR_LF
                            + tempFlights.get(2 * i + 1).getFligthNOString();
                    tableContent[i][1] = tempFlights.get(2 * i).getDeptTime().toString() + Constant.CR_LF
                            + tempFlights.get(2 * i).getArriTime().toString() + Constant.CR_LF + tempFlights.get(2 * i + 1).getDeptTime().toString()
                            + Constant.CR_LF + tempFlights.get(2 * i + 1).getArriTime().toString();
                    tableContent[i][2] = tempFlights.get(2 * i).getDeptAirportString() + Constant.CR_LF
                            + tempFlights.get(2 * i).getArriAirportString() + Constant.CR_LF + tempFlights.get(2 * i + 1).getDeptAirportString()
                            + Constant.CR_LF + tempFlights.get(2 * i + 1).getArriAirportString();
                    tableContent[i][3] = Constant.CR_LF
                            + "          "
                            + (Integer.parseInt(tempFlights.get(2 * i).getPriceString()) + Integer.parseInt(tempFlights.get(2 * i + 1)
                            .getPriceString())) + " RMB";
                }

                fillTable(tableContent);
            } else {
                JOptionPane.showMessageDialog(null, "Keep both or neither of the date blank!", "Error", JOptionPane.ERROR_MESSAGE);
                return;
            }

        }
    }

    private class bookButtonHandler implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            List<Flight> temp = new ArrayList<Flight>();
            if (chosenRow == -1) {
                JOptionPane.showMessageDialog(null, "Please choose one flight!", "Error", JOptionPane.ERROR_MESSAGE);
            } else {
                Printer.p(flights.size());
                temp.add(flights.get(2 * chosenRow));
                temp.add(flights.get(2 * chosenRow + 1));
                new BookUI(client, temp);
            }
        }

    }

}

class Progress extends Thread {
    private final int[] progressValue = {2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56,
            58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100};
    private JProgressBar progressBar;
    private JComboBox<String> comboBox1;
    private JComboBox<String> comboBox2;
    private JComboBox<String> comboBox3;
    private JComboBox<String> comboBox4;
    private JComboBox<String> comboBox5;
    private JComboBox<String> comboBox6;
    private JComboBox<String> comboBox7;
    private JComboBox<String> comboBox8;
    private JButton button;

    public Progress(JProgressBar progressBar, JComboBox<String> comboBox1, JComboBox<String> comboBox2, JComboBox<String> comboBox3,
                    JComboBox<String> comboBox4, JComboBox<String> comboBox5, JComboBox<String> comboBox6, JComboBox<String> comboBox7,
                    JComboBox<String> comboBox8, JButton button) {
        this.progressBar = progressBar;
        this.comboBox1 = comboBox1;
        this.comboBox2 = comboBox2;
        this.comboBox3 = comboBox3;
        this.comboBox4 = comboBox4;
        this.comboBox5 = comboBox5;
        this.comboBox6 = comboBox6;
        this.comboBox7 = comboBox7;
        this.comboBox8 = comboBox8;
        this.button = button;
    }

    public void run() {
        for (int i = 0; i < progressValue.length; i++) {
            try {
                Thread.sleep(25);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            progressBar.setValue(progressValue[i]);
        }
        progressBar.setIndeterminate(false);
        progressBar.setString("Information update finished!");

        comboBox1.setEnabled(true);
        comboBox2.setEnabled(true);
        comboBox3.setEnabled(true);
        comboBox4.setEnabled(true);
        comboBox5.setEnabled(true);
        comboBox6.setEnabled(true);
        comboBox7.setEnabled(true);
        comboBox8.setEnabled(true);
        button.setEnabled(true);
    }
}
